import re
from django.conf import settings
import requests
from rest_framework import serializers
from django.contrib.auth import authenticate
from .models import User
from django.conf import settings
from rest_framework import serializers
from django.conf import settings
import json
import base64
from Crypto.Cipher import AES
import binascii
import logging

logger = logging.getLogger(__name__)
class UserSimpleSerializer(serializers.ModelSerializer):
    """用于其他模块引用的简化用户序列化器"""
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'avatar']

class UserRegisterSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, min_length=8)
    
    class Meta:
        model = User
        fields = ['username', 'password', 'phone', 'user_type']
        extra_kwargs = {
            'email': {'required': False},
            'user_type': {'default': 'consumer'}
        }

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = [
            'id',
            'username',
            'nickname',
            'email',
            'phone',
            'avatar',
            'bio',
            'points',
            'user_type',
            'city',
            'district',
            'is_verified',
            'last_active',
            'openid',  # 添加openid字段
            'unionid'
        ]
        read_only_fields = [
            'id', 
            'username', 
            'user_type', 
            'is_verified', 
            'last_active',
            'openid',  # 将openid设为只读
            'unionid'
        ]

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = [
            'id', 'username', 'email', 'phone', 
            'city', 'district', 'points', 
            'is_verified', 'last_active', 'user_type'
        ]
        read_only_fields = ['id', 'user_type', 'is_verified']

class CustomerCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['username', 'phone', 'city', 'district']
        extra_kwargs = {'phone': {'required': True}}

class CustomerUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['phone', 'city', 'district', 'avatar', 'bio']

class SimpleUserSerializer(serializers.ModelSerializer):
    user = UserSimpleSerializer(read_only=True)
    
    class Meta:
        model = User
        fields = ['id', 'user', 'specialty', 'rating']

def get_openid_from_wechat(code):
    """调用微信API获取openid"""
    try:
        response = requests.get(
            'https://api.weixin.qq.com/sns/jscode2session',
            params={
                'appid': settings.WECHAT_APPID,
                'secret': settings.WECHAT_SECRET,
                'js_code': code,
                'grant_type': 'authorization_code'
            },
            timeout=5
        )
        data = response.json()
        return data.get('openid')
    except Exception as e:
        print(f"微信API调用失败: {e}")
        return None

# accounts/serializers.py

from django.contrib.auth import get_user_model
from rest_framework import serializers
import re

User = get_user_model()

class WeChatLoginSerializer(serializers.Serializer):
    code = serializers.CharField(required=True, error_messages={"required": "微信code不能为空"})
    encryptedData = serializers.CharField(required=False, allow_blank=True)
    iv = serializers.CharField(required=False, allow_blank=True)
    user_info = serializers.JSONField(required=False, allow_null=True)
    city = serializers.CharField(required=False, allow_blank=True)  # 新增城市字段验证

    def validate_code(self, value):
        """单独验证code不为空"""
        if not value.strip():
            raise serializers.ValidationError("微信code不能为空")
        return value

    
# accounts/serializers.py


class BindPhoneSerializer(serializers.ModelSerializer):
    encrypted_data = serializers.CharField(required=True)  # 微信加密数据
    iv = serializers.CharField(required=True)              # 解密向量
    
    class Meta:
        model = User
        fields = []
    
    def validate(self, data):
        """
        解密微信手机号
        参考微信官方文档：https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
        """
        try:
            # 1. 准备解密参数
            session_key = self.context['request'].session.get('wechat_session_key')
            if not session_key:
                raise serializers.ValidationError("缺少微信session_key")
            
            encrypted_data = data['encrypted_data']
            iv = data['iv']
            
            # 2. Base64解码
            session_key_bytes = base64.b64decode(session_key)
            encrypted_data_bytes = base64.b64decode(encrypted_data)
            iv_bytes = base64.b64decode(iv)
            
            # 3. AES解密
            cipher = AES.new(session_key_bytes, AES.MODE_CBC, iv_bytes)
            decrypted = cipher.decrypt(encrypted_data_bytes)
            
            # 4. 去除填充
            decrypted = self._unpad(decrypted).decode('utf-8')
            decrypted_data = json.loads(decrypted)
            
            # 5. 获取手机号
            phone_number = decrypted_data.get('purePhoneNumber') or decrypted_data.get('phoneNumber')
            if not phone_number:
                raise serializers.ValidationError("解密后未获取到手机号")
            
            # 6. 验证手机号是否已被绑定
            if User.objects.filter(phone=phone_number).exclude(id=self.instance.id).exists():
                raise serializers.ValidationError("该手机号已被其他账号绑定")
            
            # 7. 更新用户手机号
            self.instance.phone = phone_number
            self.instance.save()
            
            return {'phone': phone_number}
            
        except (binascii.Error, ValueError, json.JSONDecodeError) as e:
            raise serializers.ValidationError(f"数据解密失败: {str(e)}")
        except Exception as e:
            raise serializers.ValidationError(f"处理手机号时出错: {str(e)}")
    
    def _unpad(self, s):
        """PKCS#7去填充"""
        return s[:-ord(s[len(s)-1:])]